home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-19 | 27.3 KB | 895 lines | [TEXT/CWIE] |
- /*
- File: ProxyToken.c
-
- Contains: A proxy token acts on behalf of some other group
- of objects (for example, the selection)
-
- Written by: Greg Anderson
-
- Copyright: © 1993-1995 by Apple Computer, Inc., all rights reserved.
-
- <10> 6/23/95 ga
- */
-
- #ifdef MWTRACEBACKTABLES
- #pragma traceback on
- #endif
-
-
- #include "ProxyToken.h"
- #include "ScriptableObjectList.h"
- #include "AbstractSearchSpec.h"
-
- #include "MoreAEM.h"
-
- #define pProperties 'prps' // The "properties" property
-
- #include <AppleEvents.h>
- #include <AERegistry.h>
- #include <ASRegistry.h>
- #include <AEPackObject.h>
- #include <OSUtils.h>
-
- #include "Exceptions.h"
-
-
- #include "Debug.h"
-
-
- //========================================================================================
- // CLASS TProxyToken
- //
- // This token represents a group of other objects
- //========================================================================================
-
- #pragma segment ObjectResident
- ImplementSmallClassData(TProxyToken, clProxyToken);
-
- #pragma segment ProxyToken
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::TProxyToken:
- //----------------------------------------------------------------------------------------
- TProxyToken::TProxyToken()
- {
- } // TProxyToken::TProxyToken
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::~TProxyToken:
- //----------------------------------------------------------------------------------------
- TProxyToken::~TProxyToken()
- {
- } // TProxyToken::~TProxyToken
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::IProxyToken:
- //----------------------------------------------------------------------------------------
- void TProxyToken::IProxyToken(TAbstractScriptableObject* objectOfDesignation)
- {
- TAbstractDesignator::IAbstractDesignator(objectOfDesignation);
- } // TProxyToken::IProxyToken
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::DerivedFromOSLClass:
- //----------------------------------------------------------------------------------------
- Boolean TProxyToken::DerivedFromOSLClass(const TAETransaction& t, DescType objectClass)
- {
- return (objectClass == cProxy) || (Inherited::DerivedFromOSLClass(t, objectClass));
- } // TProxyToken::DerivedFromOSLClass
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::DefaultType:
- //
- // The default type of a proxy token is typeAEList so that the selection will always
- // return a list, even if only one item is selected. 'typeAEList' isn't really a type
- // that can be generated (it has to be a list of something), so the best type of this
- // object (typeObjectSpecifier, in this case) is used to determine what should go in
- // the list.
- //----------------------------------------------------------------------------------------
- DescType TProxyToken::DefaultType(const TAETransaction& t, DescType propertyName)
- {
- DescType defaultType = 0;
-
- if(propertyName == pContents)
- defaultType = typeAEList;
- else if(this->PropertyAppliesToProxy(propertyName))
- defaultType = Inherited::DefaultType(t, propertyName);
- else
- {
- #if 0
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- TAbstractScriptableObject* token = iter->Current(t);
- DescType defaultOfThisToken = token->DefaultType(t, propertyName);
- token->DisposeDesignator();
-
- //
- // If we don't have a default type yet, just remember this
- // token's default type
- //
- if(defaultType == 0)
- defaultType = defaultOfThisToken;
- //
- // If all of the tokens are in agreement about their default type,
- // then we'll use that. Otherwise, use typeWildCard to indicate
- // that there are multiple best types to use.
- //
- else if(defaultType != defaultOfThisToken)
- defaultType = typeWildCard;
- }
- #else
- defaultType = typeWildCard;
- #endif
- }
-
- return defaultType;
- } // TProxyToken::DefaultType
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::BestType:
- //----------------------------------------------------------------------------------------
- DescType TProxyToken::BestType(const TAETransaction& t, DescType propertyName)
- {
- DescType bestType = 0;
-
- if(propertyName == pContents)
- bestType = typeObjectSpecifier;
- else if(this->PropertyAppliesToProxy(propertyName))
- bestType = Inherited::BestType(t, propertyName);
- else
- {
- #if 0
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- TAbstractScriptableObject* token = iter->Current(t);
- DescType bestOfThisToken = token->BestType(t, propertyName);
- token->DisposeDesignator();
-
- //
- // If we don't have a best type yet, just remember this
- // token's best type
- //
- if(bestType == 0)
- bestType = bestOfThisToken;
- //
- // If all of the tokens are in agreement about their best type,
- // then we'll use that. Otherwise, use typeWildCard to indicate
- // that there are multiple best types to use.
- //
- else if(bestType != bestOfThisToken)
- bestType = typeWildCard;
- }
- #else
- bestType = typeBest;
- #endif
- }
-
- return bestType;
- } // TProxyToken::BestType
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::Exists:
- //
- // A proxy token exists if it is posible to access at least one element from it.
- //----------------------------------------------------------------------------------------
- Boolean TProxyToken::Exists(const TAETransaction& t)
- {
- TAbstractScriptableObject* token = nil;
- Boolean exists = false;
- OSErr err = noErr;
-
- NOREGISTER(token);
-
- Try
- {
- //
- // Accessing the first element is faster than doing a count,
- // even though it may allocate memory
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- token = iter->GetIndexedElement(t, typeWildCard, 1);
-
- //
- // AccessByIndex should fail rather than return nil,
- // but we'll check anyway.
- //
- if(token != nil)
- exists = true;
- }
- Catch(err)
- {
- }
-
- //
- // Delete the token if it was cloned
- //
- if(token != nil)
- token->DisposeDesignator();
-
- return exists;
- } // TProxyToken::Exists
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::DirectObjectIterator:
- //
- // By default, the elements of a proxy token are the same as its children; therefore,
- // DirectObjectIterator calls through to ElementIterator. This is not always true,
- // however; see TMarkToken::DirectObjectIterator
- //----------------------------------------------------------------------------------------
- TAbstractObjectIterator* TProxyToken::DirectObjectIterator(const TAETransaction& t)
- {
- return this->ElementIterator(t);
- } // TProxyToken::DirectObjectIterator
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::PropertyAppliesToProxy:
- //----------------------------------------------------------------------------------------
- Boolean TProxyToken::PropertyAppliesToProxy(DescType propertyName)
- {
- //
- // Used for properties and ordinals. All of the ordinals except
- // 'kAEAll' apply to the proxy.
- //
- // Note that the selection token adds pContents and kAEAll, but
- // the mark token does not. This is because "contents of selection"
- // should return all of the items in the selection (that is, the
- // "contents" property applies to the proxy "selection," not to
- // the items designated by the proxy), but "contents of every disk"
- // should return every item inside of every disk (that is, the
- // "contents" property applies to the tokens designated by the
- // proxy "every disk," not to the proxy itself).
- //
- // WARNING: Do not add properties or ordinals here lightly!
- // This simple function has a profound impact on the
- // way the foundation classes function. If you get
- // one wrong, the code will do _strange_ things
- // with that property!
- //
- return ( (propertyName == kAEFirst) ||
- (propertyName == kAELast) ||
- (propertyName == kAEMiddle) ||
- (propertyName == kAEAny) ||
- (propertyName == pBestType) ||
- (propertyName == pDefaultType)
- );
- } // TProxyToken::PropertyAppliesToProxy
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::AccessByOrdinal:
- //----------------------------------------------------------------------------------------
- TAbstractScriptableObject* TProxyToken::AccessByOrdinal(const TAETransaction& t, DescType desiredClass, DescType ordinal)
- {
- TAbstractScriptableObject* resultToken = nil;
- NOREGISTER(resultToken);
- OSErr err = noErr;
-
- if(this->PropertyAppliesToProxy(ordinal))
- {
- resultToken = Inherited::AccessByOrdinal(t, desiredClass, ordinal);
- }
- else
- {
- TAbstractScriptableObject* token = nil;
-
- NOREGISTER(token);
-
- //
- // If a script command asks for a property of a proxy object,
- // the result returned will be a list of said property retrieved
- // from every item represented by the proxy
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
- TAbstractScriptableObject* ordinalToken = token->AccessByOrdinal(t, desiredClass, ordinal);
- ordinalToken->AddThisToMarkToken(resultToken, kSingleItemOrUnion);
- token->DisposeDesignator();
- token = nil;
- }
- Catch(err)
- {
- if(token != nil)
- token->DisposeDesignator();
- if(resultToken != nil)
- resultToken->DisposeDesignator();
-
- //
- // ••• should we really fail again? maybe we
- // should not return an error if there is at
- // least one item in the proxy that returns
- // a valid property. For now, we only allow
- // 'no such object' to pass through.
- //
- if(err != errAENoSuchObject)
- Throw(err);
- }
- }
- }
-
- //
- // Since we allow 'no such object' to pass through above,
- // we must fail here if nothing at all was found.
- //
- if(resultToken == nil)
- FailErr(errAENoSuchObject);
-
- return resultToken;
- } // TProxyToken::AccessByOrdinal
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::AccessByProperty:
- //----------------------------------------------------------------------------------------
- TAbstractScriptableObject* TProxyToken::AccessByProperty(const TAETransaction& t, DescType propertyName)
- {
- TAbstractScriptableObject* resultToken = nil;
- OSErr err = noErr;
-
- NOREGISTER(resultToken);
-
- //
- // Although most properties of the proxy object apply to its elements,
- // there are a few that apply to the 'proxy' object itself.
- // (You can always say 'default type of every item of <proxy object>' to
- // get these properties as they apply to the elements represented by proxy)
- //
- // Note the special checking for pProperties; we want to generate an
- // ordinary generic token, pProperties of <this proxy> (which we wouldn't
- // get if we tried to look for 'pProperties' in the property list), but we want
- // the GetProperty call to delegate to the tokens of the proxy (which it
- // wouldn't do if pProperties was in 'PropertyAppliesToProxy')
- //
- // ◊Script: pContents, pEntireContents here?
- //
- if(this->PropertyAppliesToProxy(propertyName) || (propertyName == pProperties))
- {
- resultToken = Inherited::AccessByProperty(t, propertyName);
- }
- else
- {
- //
- // 'propertyDescription.PropertyIdentifier()' will come back zero if this property is not in
- // the property table of any of the items this proxy designates
- //
- TPropertyDescription propertyDescription = this->LookupPropertyDesciption(t, propertyName);
-
- if((propertyDescription.PropertyIdentifier() != 0) && (NeverCreateGenericProperty(propertyDescription.AdditionalInfo()) == false))
- {
- resultToken = new TGenericProperty;
- ((TGenericProperty*)resultToken)->IGenericProperty(this, propertyDescription);
- }
- else
- {
- TAbstractScriptableObject* token = nil;
-
- NOREGISTER(token);
-
- //
- // If a script command asks for a property of a proxy object,
- // the result returned will be a list of said property retrieved
- // from every item represented by the proxy
- //
- // ◊Script: We need to call AccessByProperty in case that the
- // property being accessed is really a reference
- // to some object (e.g. the trash); however,
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
- TAbstractScriptableObject* propertyToken = token->AccessByProperty(t, propertyName);
- propertyToken->AddThisToMarkToken(resultToken, kPropertyUnion); // was: kSingleItemOrUnion
- token->DisposeDesignator();
- token = nil;
- }
- Catch(err)
- {
- if(token != nil)
- token->DisposeDesignator();
- if(resultToken != nil)
- resultToken->DisposeDesignator();
-
- //
- // ••• should we really fail again? maybe we
- // should not return an error if there is at
- // least one item in the proxy that returns
- // a valid property. For now, we only allow
- // 'no such object' to pass through.
- //
- if(err != errAENoSuchObject)
- Throw(err);
- }
- }
- }
- }
-
- //
- // Since we allow 'no such object' to pass through above,
- // we must fail here if nothing at all was found.
- //
- if(resultToken == nil)
- FailErr(errAENoSuchObject);
-
- return resultToken;
- } // TProxyToken::AccessByProperty
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::BuildObjectSpecifier:
- //----------------------------------------------------------------------------------------
- TDescriptor TProxyToken::BuildObjectSpecifier(const TAETransaction& t)
- {
- TDescriptor result;
- OSErr err = noErr;
-
- TAbstractScriptableObject* token = nil;
- TDescriptor specifierOfOneObject;
-
- NOREGISTER(token);
-
- //
- // If we need to build an object specifier for a proxy,
- // we instead build a specifier for every element that
- // the proxy represents.
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
-
- specifierOfOneObject = token->BuildObjectSpecifier(t);
- result.AddItemToList(specifierOfOneObject);
- specifierOfOneObject.Dispose();
-
- token->DisposeDesignator();
- }
- Catch(err)
- {
- specifierOfOneObject.Dispose();
- if(token != nil)
- token->DisposeDesignator();
-
- result.Dispose();
- Throw(err);
- }
- }
-
- return result;
- } // TProxyToken::BuildObjectSpecifier
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::CanReturnDataOfType:
- //----------------------------------------------------------------------------------------
- Boolean TProxyToken::CanReturnDataOfType(const TAETransaction& t, DescType propertyName, DescType desiredType)
- {
- TAbstractScriptableObject* token = nil;
- Boolean canDoIt = true;
- Boolean canDoOne = false;
- OSErr err = noErr;
-
- NOREGISTER(token);
-
- if(this->PropertyAppliesToProxy(propertyName) == false)
- {
- //
- // The proxy object can return data of a given type if
- // and only if all of the objects it represents can
- // also return that type.
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
- canDoIt = token->CanReturnDataOfType(t, propertyName, desiredType);
- token->DisposeDesignator();
- token = nil;
- canDoOne = true;
- }
- Catch(err)
- {
- canDoIt = false;
- if(token != nil)
- token->DisposeDesignator();
- }
-
- if(!canDoIt)
- break;
- }
- }
-
- //
- // If you can't do at least one, then you can't do it
- //
- if(canDoOne == false)
- canDoIt = false;
-
- //
- // If the proxy objects can't return the specified type,
- // it is still possible to make object specifiers & c.
- //
- if(canDoIt == false)
- canDoIt = Inherited::CanReturnDataOfType(t, propertyName, desiredType);
-
- return canDoIt;
- } // TProxyToken::CanReturnDataOfType
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::LookupPropertyDesciption
- //----------------------------------------------------------------------------------------
- TPropertyDescription TProxyToken::LookupPropertyDesciption(const TAETransaction& t, DescType propertyIdentifier)
- {
- TAbstractScriptableObject* token = nil;
- TPropertyDescription propertyDescription;
- OSErr err = noErr;
-
- propertyDescription.fPropertyIdentifier = 0;
-
- NOREGISTER(token);
-
- //
- // The proxy object can return data of a given type if
- // and only if all of the objects it represents can
- // also return that type.
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
- const TPropertyDescription* oneDescription = token->DescriptionOfProperty(t, propertyIdentifier);
- token->DisposeDesignator();
- token = nil;
- if(oneDescription != nil)
- {
- if(propertyDescription.PropertyIdentifier() != propertyIdentifier)
- propertyDescription = *oneDescription;
- else if(propertyDescription != *oneDescription)
- FailErr(errAEEventFailed); // ◊Error: Need an error for 'incompatible properties
- }
- // ◊Error: What should we do if the property is unknown?
- // If it is unknown in all, we should return. If it is unknown
- // in some, we should probably fail with the same error as above
- }
- Catch(err)
- {
- if(token != nil)
- token->DisposeDesignator();
- Throw(err);
- }
- }
-
- return propertyDescription;
- }
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::GetProperty:
- //----------------------------------------------------------------------------------------
- TDescriptor TProxyToken::GetProperty(const TAETransaction& t, DescType propertyName, DescType desiredType, unsigned long additionalInfo /*= 0*/)
- {
- TAbstractScriptableObject* token = nil;
- TDescriptor resultList;
- TDescriptor intermediate;
- OSErr err = noErr;
-
- NOREGISTER(token);
-
- if(this->PropertyAppliesToProxy(propertyName))
- resultList = Inherited::GetProperty(t, propertyName, desiredType, additionalInfo);
- else
- {
- //
- // Get data from all of the objects represented by proxy
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
- intermediate = token->GetDataOfType(t, propertyName, desiredType, additionalInfo);
- resultList.AppendListAndDispose(intermediate);
- intermediate.ClearDescriptor();
- token->DisposeDesignator();
- token = nil;
- }
- Catch(err)
- {
- intermediate.Dispose();
- if(token != nil)
- token->DisposeDesignator();
-
- resultList.Dispose();
- Throw(err);
- }
- }
- }
-
- return resultList;
- } // TProxyToken::GetProperty
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::SetProperty:
- //----------------------------------------------------------------------------------------
- void TProxyToken::SetProperty(const TAETransaction& t, DescType propertyName, TDescriptor& data, unsigned long additionalInfo /*= 0*/)
- {
- TAbstractScriptableObject* token = nil;
- long err = noErr;
-
- NOREGISTER(token);
-
- if(this->PropertyAppliesToProxy(propertyName))
- Inherited::SetProperty(t, propertyName, data, additionalInfo);
- else
- {
- //
- // Pass the set data command on to each object represented by proxy
- // Since the order that we try to set these objects in is arbitrary,
- // try to set all of them, but report an error if any one fails.
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
- token->SetProperty(t, propertyName, data, additionalInfo);
- token->DisposeDesignator();
- token = nil;
- }
- Catch(err)
- {
- if(token != nil)
- token->DisposeDesignator();
- }
- }
- }
-
- FailErr(err);
- } // TProxyToken::SetProperty
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::AECommandDispatch:
- //----------------------------------------------------------------------------------------
- TDescriptor TProxyToken::AECommandDispatch(const TAETransaction& t, long aeCommandID, long auxInfo /* = 0 */)
- {
- AListOf<TAbstractScriptableObject*>* itemList = this->ConvertThisToList(t, aeCommandID);
- TDescriptor result;
-
- //
- // In the outer loop, do one dispatch involving as
- // many items as possible (all that want the same
- // command dispatcher and the same dispatch selector).
- // The outer loop exits once every item in the list
- // has been added to a collection and dispatched.
- //
- while(itemList->Empty() == false)
- {
- long dispatchSelector = 0;
- TAbstractScriptableObject* dispatcher = nil;
- TAbstractScriptableObject* collection = nil;
-
- //
- // Loop through the items in 'itemList', take all of the
- // items that want the same dispatcher and dispatch selector
- // as the first item and put them into the collection
- //
- for(AnIteratorOfAListOf<TAbstractScriptableObject*> iter(itemList); iter.More(); iter.Next())
- {
- long oneDispatchSelector = 0;
- TAbstractScriptableObject* oneDispatcher = iter.Current()->GetAECommandDispatcher(t, aeCommandID, auxInfo, oneDispatchSelector);
-
- //
- // If we don't have a collection yet, record the
- // dispatcher and selector we'll be collecting
- // for on this iteration of the loop
- //
- if(collection == nil)
- {
- dispatcher = oneDispatcher;
- dispatchSelector = oneDispatchSelector;
- }
-
- //
- // If we have a match, add this item to the
- // collection and remove it from this loop so
- // that it will not be considered again.
- //
- // n.b. If the item is a designator, then it
- // was cloned when the list was created and
- // will be disposed when the collection is
- // deleted.
- //
- if((dispatcher == oneDispatcher) && (dispatchSelector == oneDispatchSelector))
- {
- iter.Current()->AddThisToMarkToken(collection, kSingleItemOrUnion);
- iter.RemoveCurrent();
- }
- }
-
- //
- // At this point we should ALWAYS have a collection.
- //
- if(collection != nil)
- {
- TDescriptor intermediate;
-
- //
- // If the dispatcher is nil, then send the command directly
- // to the items in the collection. This will happen one item
- // at a time; in fact, it's a bit of a waste to make a collection
- // just to do this. A better optimization would be to have
- // a special loop just for items with a nil dispatcher, and
- // send them off directly.
- //
- // In practice, though, no one should ever call AECommandDispatch
- // unless there's a chance that the command will get dispatched
- // to some other object, so this case (dispatcher == nil) should
- // be rare.
- //
- if(dispatcher == nil)
- intermediate = collection->AECommand(t, aeCommandID, nil, auxInfo);
- else
- {
- intermediate = dispatcher->AECommand(t, aeCommandID, collection, auxInfo);
- dispatcher->DisposeDesignator();
- }
- collection->DisposeDesignator();
- collection = nil;
-
- result.AppendListAndDispose(intermediate);
- }
- }
-
- delete itemList;
-
- return result;
- } // TProxyToken::AECommandDispatch
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::AECommand:
- //----------------------------------------------------------------------------------------
- TDescriptor TProxyToken::AECommand(const TAETransaction& t, long aeCommandID, TAbstractScriptableObject* auxObjects /* = nil */, long auxInfo /* = 0 */)
- {
- TAbstractScriptableObject* token = nil;
- TDescriptor resultList;
- TDescriptor resultDesc;
- Boolean atLeastOneWorked = false;
- long err = noErr;
-
- NOREGISTER(token);
-
- //
- // Important: The index of each window will change as
- // they are closed, so we must reverse the order of iteration
- // if the command is kAEClose. The same is true of delete.
- //
- // I suppose we could do every command backwards, but
- // that seems a little bit strange
- //
- // Note: 'Select' also has to go backwards, because
- // selecting an item may bring it to the end of the list
- // (this is true in the Finder, at least).
- //
- Boolean direction = kForwardIteration;
- if((aeCommandID == kAEClose) || (aeCommandID == kAESelect) || (aeCommandID == kAEDelete))
- direction = kBackwardIteration;
-
- //
- // Pass the command on to each object represented by proxy
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t, direction); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
- resultDesc = token->AECommand(t, aeCommandID, auxObjects, auxInfo);
- resultList.AppendListAndDispose(resultDesc);
- resultDesc.ClearDescriptor();
- token->DisposeDesignator();
- token = nil;
- atLeastOneWorked = true;
- }
- Catch(err)
- {
- resultDesc.Dispose();
- if(token != nil)
- token->DisposeDesignator();
- }
- }
-
- //
- // If at least one item in the set knew how to do the
- // command, then ignore those that didn't know how
- // to do the command (should we be even more generous
- // about hiding errors if at least one item worked?)
- //
- if(atLeastOneWorked && (err == errAEEventNotHandled))
- err = noErr;
-
- //
- // If there was an error, dispose the result and pass the error along
- //
- if(err != noErr)
- {
- resultList.Dispose();
- FailErr(err);
- }
-
- return resultList;
- } // TProxyToken::AECommand
-
- //----------------------------------------------------------------------------------------
- // TProxyToken::CreateNewElement:
- //----------------------------------------------------------------------------------------
- TAbstractScriptableObject* TProxyToken::CreateNewElement(const TAETransaction& t, DescType newObjectClass, TDescriptor initialData, TDescriptor initialProperties, Boolean& usedInitialData, Boolean& usedInitialProperties)
- {
- TAbstractScriptableObject* token = nil;
- TAbstractScriptableObject* resultToken = nil;
- TAbstractScriptableObject* createdToken = nil;
- long err = noErr;
-
- NOREGISTER(token);
- NOREGISTER(resultToken);
- NOREGISTER(createdToken);
-
- //
- // Pass the create command on to each object represented by proxy
- //
- TAbstractObjectIterator* iter = this->DirectObjectIterator(t);
- for(iter->Reset(t); iter->More(t); iter->Next(t))
- {
- Try
- {
- token = iter->Current(t);
-
- //
- // ◊Script: what happens if different calls to 'create' return different
- // values for 'unsedInitialData' and 'usedInitialProperties'? This would be
- // very bad, but it should never happen, because the return value of these
- // booleans should depend on the new object's class and nothing else.
- //
- createdToken = token->CreateNewElement(t, newObjectClass, initialData, initialProperties, usedInitialData, usedInitialProperties);
- createdToken->AddThisToMarkToken(resultToken, kSingleItemOrUnion);
-
- createdToken = nil;
- token->DisposeDesignator();
- token = nil;
- }
- Catch(err)
- {
- if(createdToken != nil)
- createdToken->DisposeDesignator();
- createdToken = nil;
- if(token != nil)
- token->DisposeDesignator();
- token = nil;
- }
- }
-
- //
- // If there was an error, dispose the result and pass the error along
- //
- if(err != noErr)
- {
- if(resultToken != nil)
- resultToken->DisposeDesignator();
- FailErr(err);
- }
-
- return resultToken;
- } // TProxyToken::CreateNewElement
-
-
- #pragma segment CFrontCruft
-